package com.example.demo.controller;

import com.example.demo.entity.Article;
import com.example.demo.service.ArticleService;
import com.example.demo.util.CheckShareLinkEnableUtil;
import com.example.demo.util.Consts;
import com.example.demo.util.StringUtil;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.util.CryptographyUtil;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 用户控制器
 */
@Controller
@RequestMapping(value = "/user")//通过它来指定控制器可以处理哪些URL请求，相当于Servlet中在web.xml中配置
public class UserController {

    @Autowired //父类或抽象类中存在公共依赖的bean时
    UserService userService;

    @Autowired
    private ArticleService articleService;
    /**
     * 用户注册
     */
    @ResponseBody   //将java对象转为json格式的数据。将 HTTP 请求正文插入方法中，使用适合的 HttpMessageConverter 将请求体写入某个对象。
    @RequestMapping("/register")
    public Map<String,Object> login(@Valid User user, BindingResult bindingResult){
        Map<String,Object> map=new HashMap<>();
        if(bindingResult.hasErrors()){
            map.put("success",false);
            map.put("errorInfo",bindingResult.getFieldError().getDefaultMessage());
        }else if(userService.findByUserName(user.getUserName())!=null){
            map.put("success",false);
            map.put("errorInfo","用户名已存在，请更换！");
        }else{
            user.setPassword(CryptographyUtil.md5(user.getPassword(), CryptographyUtil.SALT));
            userService.save(user);
            map.put("success",true);
        }
        return map;
    }
    /**
     * 用户登录
     */
    @ResponseBody
    @PostMapping("/login")
    public Map<String,Object> login(User user, HttpSession session){
        Map<String,Object> map = new HashMap<>();
        if(StringUtil.isEmpty(user.getUserName())){
            map.put("success",false);
            map.put("errorInfo","请输入用户名！");
        }else if(StringUtil.isEmpty(user.getPassword())){
            map.put("success",false);
            map.put("errorInfo","请输入密码！");
        }else{
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),CryptographyUtil.md5(user.getPassword(),CryptographyUtil.SALT));
            try {
                subject.login(token);       //登录验证
                String userName = (String) SecurityUtils.getSubject().getPrincipal();
                User currentUser = userService.findByUserName(userName);
                    userService.save(currentUser);
                    session.setAttribute(Consts.CURRENT_USER,currentUser);
                    map.put("success", true);

            }catch (Exception e){
                e.printStackTrace();
                map.put("success", false);
                map.put("errorInfo", "用户名或密码错误！");
            }

        }
        return map;
    }
    /**
     * 资源管理
     */
    @GetMapping("/articleManage")
    public String articleManage(){
        return "/user/articleManage";
    }

    /**
     * 根据条件分页查询资源信息列表（只显示当前登录用户的资源）
     * @param s_article
     * @param page
     * @param pageSize
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/articleList")
    public Map<String,Object> articleList(Article s_article, @RequestParam(value="page",required = false) Integer page,
                                          @RequestParam(value="limit",required = false) Integer pageSize, HttpSession session){
        Map<String,Object> map = new HashMap<>();
        User currentUser = (User) session.getAttribute(Consts.CURRENT_USER);
        s_article.setUser(currentUser);
        map.put("data",articleService.list(s_article,null,null,null,page,pageSize,
                Sort.Direction.DESC,"publishDate"));
        map.put("count",articleService.getCount(s_article,null,
                null,null));     //总计录数
        map.put("code",0);
        return map;
    }

    /**
     * 进入资源发布页面
     */
    @GetMapping("toAddArticle")
    public String toAddArticle(){
        return "/user/addArticle";
    }

    /**
     * 添加或修改资源
     */
    @ResponseBody
    @PostMapping("/saveArticle")
    public Map<String,Object> saveArticle(Article article,HttpSession session) throws IOException {
        Map<String,Object> resultMap = new HashMap<>();
        if(article.getPoints()<0||article.getPoints()>10){
            resultMap.put("success",false);
            resultMap.put("erroInfo","积分超出正常区间！");
            return resultMap;
        }
        if(!CheckShareLinkEnableUtil.check(article.getDownload())){
            resultMap.put("success",false);
            resultMap.put("erroInfo","百度云分享链接已经失效，请重新发布！");
            return resultMap;
        }
        User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
        if(article.getArticleId()==null){               //添加资源
            article.setPublishDate(new Date());
            article.setUser(currentUser);
            if(article.getPoints()==0){         //积分为0时，设置为免费资源
                article.setFree(true);
            }
            article.setState(1);                //未审核状态
            article.setClick(new Random().nextInt(150)+50);         //设置点击数为50~200
            articleService.save(article);
            resultMap.put("success",true);
        }else{                              //修改资源
            Article oldArticle = articleService.getById(article.getArticleId());        //获取实体
            if(oldArticle.getUser().getUserId().intValue()==currentUser.getUserId().intValue()){        //只能修改自己的资源
                oldArticle.setName(article.getName());
                oldArticle.setArcType(article.getArcType());
                oldArticle.setDownload(article.getDownload());
                oldArticle.setPassword(article.getPassword());
                oldArticle.setKeywords(article.getKeywords());
                oldArticle.setDescription(article.getDescription());
                oldArticle.setContent(article.getContent());
                if(oldArticle.getState()==3){           //假如原先是未通过，用户点击修改，则重新审核，状态变成未审核
                    oldArticle.setState(1);
                }
                articleService.save(oldArticle);
                //-TODO 更新时需要把新资源信息放入lucene
                resultMap.put("success",true);
            }
        }

        return resultMap;
    }

    /**
     * 验证资源的发布者
     * @param articleId
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/checkArticleUser")
    public Map<String,Object> checkArticleUser(Integer articleId,HttpSession session){
        Map<String,Object> resultMap = new HashMap<>();
        User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
        Article article = articleService.getById(articleId);
        if(article.getUser().getUserId().intValue() == currentUser.getUserId().intValue()){
            resultMap.put("success",true);
        }else{
            resultMap.put("success",false);
            resultMap.put("erroInfo","您不是资源所有者，不能修改！");
        }
        return resultMap;
    }

    /**
     * 进入修改资源页面
     * @param articleId
     * @return
     */
    @GetMapping("/toEditArticle/{articleId}")
    public ModelAndView toEditArticle(@PathVariable(value="articleId",required = true) Integer articleId){
        ModelAndView mav = new ModelAndView();
        Article article = articleService.getById(articleId);
        mav.addObject("article",article);
        mav.setViewName("/user/editArticle");
        return mav;
    }

    /**
     * 根据id删除一条资源
     * @param articleId
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/articleDelete")
    public Map<String,Object> articleDelete(Integer articleId,HttpSession session){
        Map<String,Object> resultMap = new HashMap<>();
        User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
        Article article = articleService.getById(articleId);
        if(article.getUser().getUserId().intValue() == currentUser.getUserId().intValue()){
            //TODO 需要先删除评论
            articleService.delete(articleId);
            //TODO 需要把资源从lucene里面删掉
            resultMap.put("success",true);
        }else{
            resultMap.put("success",false);
            resultMap.put("erroInfo","您不是资源所有者，不能删除！");
        }
        return resultMap;
    }
}
